// Package utils
package utils

import (
	"fmt"
)

type SqlHelper struct {
	tableName     string        // 表名
	alias         string        // 表的别名
	selectClause  string        // SELECT子句，可选
	fromClause    string        // FROM子句，必选
	whereClause   string        // WHERE子句，可选
	orderByClause string        // ORDER BY子句，可选
	isThereAlias  bool          // 表是否有别名
	Parameters    []interface{} // WHERE子句中的参数
}

// 构造SqlHelper，生成 FROM 子句，不指定别名
// 参数：tableName - 表名
func NewSqlHelper(tableName string) *SqlHelper {
	return NewSqlHelper2(tableName, "")
}

// 构造SqlHelper，生成 FROM 子句，并指定别名
// 参数：tableName - 表名
// 参数：alias - 别名
func NewSqlHelper2(tableName, alias string) *SqlHelper {

	helper := &SqlHelper{tableName: tableName, alias: alias}

	helper.fromClause = fmt.Sprintf(" FROM %s %s ", tableName, alias)
	helper.isThereAlias = len(alias) > 0

	return helper
}

// 拼接 SELECT 子句
// 参数：field - 字段名
func (this *SqlHelper) AddSelectField(field string) *SqlHelper {
	if 0 == len(this.whereClause) {
		this.selectClause = "SELECT " + field
	} else {
		this.selectClause += ", " + field
	}

	return this
}

// 根据传递的第一个参数判断是否拼接 SELECT 子句
// 参数：isAppend - 为true则拼接，否则不拼接
// 参数：field - 字段名
func (this *SqlHelper) AddSelectField2(isAppend bool, field string) *SqlHelper {
	if isAppend {
		this.AddSelectField(field)
	}

	return this
}

// 拼接 WHERE 子句
// 参数：condition - 查询条件
// 参数：params - 查询条件对应的参数
func (this *SqlHelper) AddWhere(condition string, params ...interface{}) *SqlHelper {
	if 0 == len(this.whereClause) {
		this.whereClause = " WHERE " + condition
	} else {
		this.whereClause += " AND " + condition
	}

	// 保存参数
	this.Parameters = append(this.Parameters, params...)

	return this
}

// 拼接 WHERE 子句
// 参数：isAppend - 为true则拼接，否则不拼接
// 参数：condition - 查询条件
// 参数：params - 查询条件对应的参数
func (this *SqlHelper) AddWhere2(isAppend bool, condition string, params ...interface{}) *SqlHelper {
	if isAppend {
		this.AddWhere(condition, params...)
	}

	return this
}

// 拼接 ORDER BY 子句
// 参数：propertyName - 需要排序的属性名
// 参数：sortRule - 排序规则（ASC和DESC），传零长度字符串则以ASC排序。
func (this *SqlHelper) AddOrderBy(propertyName, sortRule string) *SqlHelper {
	if 0 == len(sortRule) {
		sortRule = "ASC"
	}

	if 0 == len(this.orderByClause) {
		this.orderByClause = fmt.Sprintf(" ORDER BY %s %s", propertyName, sortRule)
	} else {
		this.orderByClause += fmt.Sprintf(", %s %s", propertyName, sortRule)
	}

	return this
}

// 拼接 ORDER BY 子句
// 参数：isAppend - 为true则拼接，否则不拼接
// 参数：propertyName - 需要排序的属性名
// 参数：sortRule - 排序规则（ASC和DESC），传零长度字符串则以ASC排序。
func (this *SqlHelper) AddOrderBy2(isAppend bool, propertyName, sortRule string) *SqlHelper {
	if isAppend {
		this.AddOrderBy(propertyName, sortRule)
	}

	return this
}

// 获取生成的查询总记录数的 SQL语句（没有ORDER BY 子句）
// 返回：查询总记录数的SQL语句（没有ORDER BY 子句）
func (this *SqlHelper) GetQueryCountSql() string {
	return fmt.Sprintf("SELECT COUNT(*) %s%s", this.fromClause, this.whereClause)
}

// 获取生成的查询数据的 SQL语句
// 返回：查询数据的SQL语句
func (this *SqlHelper) GetQuerySql() string {
	var selectClause string
	if 0 == len(this.selectClause) {
		if this.isThereAlias {
			selectClause = "SELECT " + this.alias + ".*"
		} else {
			selectClause = "SELECT *"
		}
	} else {
		selectClause = this.selectClause
	}

	return fmt.Sprintf("%s%s%s%s", selectClause, this.fromClause, this.whereClause, this.orderByClause)
}

// 获取MySQL数据库分页查询SQL语句
// 参数：pageNum - 当前页码
// 参数：pageSize - 每页显示记录数
// 返回：MySQL数据库分页查询SQL语句
func (this *SqlHelper) GetMySQLPaginationQueryListSql(pageNum, pageSize int) string {
	return fmt.Sprintf("%s LIMIT %d,%d", this.GetQuerySql(), pageSize*(pageNum-1), pageSize)
}

// 获取PostgreSQL数据库分页查询SQL语句
// 参数：pageNum - 当前页码
// 参数：pageSize - 每页显示记录数
// 返回：MySQL数据库分页查询SQL语句
func (this *SqlHelper) GetPostgreSQLPaginationQueryListSql(pageNum, pageSize int) string {
	return fmt.Sprintf("%s LIMIT %d OFFSET %d", this.GetQuerySql(), pageSize, pageSize*(pageNum-1))
}
